#--
# Active Directory Module for Ruby
#
# Copyright (c) 2005-2006 Justin Mecham
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
#++

module ActiveDirectory

  #
  # Represents a Group object within an Active Directory instance.
  #
  class Group < Base

    # Distinguished Name (DN)
    attr_accessor :dn

    # Description
    attr_accessor :description

    # Common Name (CN)
    attr_accessor :name

    # Users who are members of this Group
    attr          :members

    #
    # Attributes that we wish to pull from Active Directory for any Group that
    # can be located within the directory.
    #
    ATTRIBUTES = ["distinguishedName",    # DN of Group
                  "name",                 # Group Name
                  "member",               # DN References to Members
                  "description"] #:nodoc: # Description

    #
    # Attempts to load a Group by a Distinguished Name (DN).
    #
    def initialize(identifier)

      identifier = identifier.delete("\\")

      load_by_dn(identifier)

    end

    #
    # Proxy for loading and returning the members of this group.
    #
    def members #:nodoc:
      members = Array.new
      unless @members.nil?
        for user_dn in @members
          members << User.new(user_dn)
        end
      end
      members
    end

    private

    #
    # Attempt to load a Group by its Distinguished Name (DN).
    #
    def load_by_dn(dn)

      if dn.nil? or dn.length == 0
        raise ArgumentError, "No distinguished name provided."
      end

      # De-escape the DN
      dn = dn.gsub(/"/, "\\\"")

      entries = Base.search(dn, LDAP::LDAP_SCOPE_BASE,
                  "(&(objectClass=group))", ATTRIBUTES)

      raise UnknownGroupError if (entries.nil? or entries.length != 1)

      parse_ldap_entry(entries[0])

    end

    def parse_ldap_entry(entry)
      @dn          = entry['distinguishedName'][0].delete("\\")
      @name        = entry['name'][0].delete("\\")
      @description = entry['description'][0] unless entry['description'].nil?
      @members     = entry['member']
    end
    
  end

end